package com.jspm.config;

import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;

@Configuration
//@EnableTransactionManagement  // 启用事务管理
public class TransactionAopConfig {

    @Bean
    public TransactionInterceptor transactionInterceptor(PlatformTransactionManager transactionManager) {
        // 1. 定义事务规则
        NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();

        // 增删改方法：REQUIRED
        RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
        requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        // 查询方法：REQUIRED + readOnly
        RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
        readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        readOnlyTx.setReadOnly(true);

        // 2. 配置方法匹配规则（完全匹配你的 XML 配置）
        source.addTransactionalMethod("add*", requiredTx);
        source.addTransactionalMethod("append*", requiredTx);
        source.addTransactionalMethod("save*", requiredTx);
        source.addTransactionalMethod("update*", requiredTx);
        source.addTransactionalMethod("modify*", requiredTx);
        source.addTransactionalMethod("edit*", requiredTx);
        source.addTransactionalMethod("insert*", requiredTx);
        source.addTransactionalMethod("delete*", requiredTx);
        source.addTransactionalMethod("remove*", requiredTx);
        source.addTransactionalMethod("repair", requiredTx);

        source.addTransactionalMethod("get*", readOnlyTx);
        source.addTransactionalMethod("find*", readOnlyTx);
        source.addTransactionalMethod("load*", readOnlyTx);
        source.addTransactionalMethod("search*", readOnlyTx);
        source.addTransactionalMethod("datagrid*", readOnlyTx);

        // 默认规则：其他方法使用 REQUIRED
        source.addTransactionalMethod("*", requiredTx);

        // 3. 创建事务拦截器
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionManager(transactionManager);
        interceptor.setTransactionAttributeSource(source);

        return interceptor;
    }

    @Bean
    public Advisor transactionAdvisor(TransactionInterceptor interceptor) {
        // 使用 AspectJ 表达式匹配目标方法（这里匹配所有 Service 层方法）
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution(* com.jspm.service..*.*(..))");

        // 返回 Advisor（切面 = 切点 + 通知）
        return new DefaultPointcutAdvisor(pointcut, interceptor);
    }
}